using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using DnsService.Interfaces;
using DnsService.Models;
using LocalDnsSdk.Commands;

namespace DnsService.Services
{
    /// <summary>
    /// 命令执行器：统一处理命令的解析、权限检查和执行
    /// 作者：系统
    /// </summary>
    public class CommandExecutor
    {
        private readonly IDnsService _dnsService;
        private readonly DnsConfigManager _configManager;
        private readonly CommandSource _source;
        
        /// <summary>
        /// 命令来源枚举
        /// </summary>
        public enum CommandSource
        {
            /// <summary>
            /// 控制台命令行
            /// </summary>
            Console,
            /// <summary>
            /// UI界面
            /// </summary>
            UI,
            /// <summary>
            /// Socket连接
            /// </summary>
            Socket
        }
        
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dnsService">DNS服务实例</param>
        /// <param name="configManager">配置管理器实例</param>
        /// <param name="source">命令来源</param>
        public CommandExecutor(IDnsService dnsService, DnsConfigManager configManager, CommandSource source)
        {
            _dnsService = dnsService;
            _configManager = configManager;
            _source = source;
        }
        
        /// <summary>
        /// 执行命令
        /// </summary>
        /// <param name="commandLine">命令行文本</param>
        /// <param name="result">执行结果</param>
        /// <returns>是否执行成功</returns>
        public bool Execute(string commandLine, out string result)
        {
            StringBuilder resultBuilder = new StringBuilder();
            
            try
            {
                // 解析命令
                if (!CommandRegistry.TryResolve(commandLine, out var command, out var args, out var parseError))
                {
                    result = parseError;
                    return false;
                }
                
                if (command == null)
                {
                    result = "命令解析失败：未获得命令实例";
                    return false;
                }
                
                // 检查权限
                if (!CheckPermission(command))
                {
                    result = $"权限不足：无法执行命令 {command.Name}";
                    return false;
                }
                
                // 验证参数
                if (!command.Validate(args, out var validationError))
                {
                    result = validationError;
                    return false;
                }
                
                // 执行对应命令
                switch (command.Name)
                {
                    case StatusCommand.NAME:
                        result = ExecuteStatusCommand();
                        break;
                        
                    case StartCommand.NAME:
                        result = ExecuteStartCommand();
                        break;
                        
                    case StopCommand.NAME:
                        result = ExecuteStopCommand();
                        break;
                        
                    case RestartCommand.NAME:
                        result = ExecuteRestartCommand();
                        break;
                        
                    case ListRecordsCommand.NAME:
                        result = ExecuteListRecordsCommand();
                        break;
                        
                    case AddCommand.NAME:
                        result = ExecuteAddCommand(args);
                        break;
                        
                    case AddPtrCommand.NAME:
                        result = ExecuteAddPtrCommand(args);
                        break;
                        
                    case RemoveCommand.NAME:
                        result = ExecuteRemoveCommand(args);
                        break;
                        
                    case ListCommandsCommand.NAME:
                        result = ExecuteListCommandsCommand();
                        break;
                        
                    case HelpCommand.NAME:
                        result = ExecuteHelpCommand(args);
                        break;
                        
                    default:
                        result = $"命令 {command.Name} 尚未实现";
                        return false;
                }
                
                return true;
            }
            catch (Exception ex)
            {
                result = $"执行命令出错: {ex.Message}";
                return false;
            }
        }
        
        /// <summary>
        /// 检查权限
        /// </summary>
        /// <param name="command">命令对象</param>
        /// <returns>是否有权限执行</returns>
        private bool CheckPermission(BaseCommand command)
        {
            // 控制台和UI拥有所有权限
            if (_source == CommandSource.Console || _source == CommandSource.UI)
            {
                return true;
            }
            
            // Socket连接只能执行User权限的命令（主要是记录操作）
            if (_source == CommandSource.Socket)
            {
                return command.Permission == CommandPermission.User;
            }
            
            return false;
        }
        
        /// <summary>
        /// 获取可用命令列表（考虑权限）
        /// </summary>
        /// <returns>可用命令列表</returns>
        public List<BaseCommand> GetAvailableCommands()
        {
            List<BaseCommand> availableCommands = new List<BaseCommand>();
            
            foreach (var command in CommandRegistry.Commands)
            {
                if (CheckPermission(command))
                {
                    availableCommands.Add(command);
                }
            }
            
            return availableCommands;
        }
        
        // 命令执行方法实现
        private string ExecuteStatusCommand()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine($"服务状态: {(_dnsService.IsRunning ? "运行中" : "已停止")}");
            if (_dnsService.IsRunning)
            {
                sb.AppendLine($"监听端口: {_dnsService.Port}");
                sb.AppendLine($"缓存记录数: {_dnsService.DnsCache.Count}");
            }
            return sb.ToString().TrimEnd();
        }
        
        private string ExecuteStartCommand()
        {
            if (_dnsService.IsRunning)
            {
                return "服务已在运行中";
            }
            
            try
            {
                _dnsService.Start();
                return "服务启动成功";
            }
            catch (Exception ex)
            {
                return $"服务启动失败: {ex.Message}";
            }
        }
        
        private string ExecuteStopCommand()
        {
            if (!_dnsService.IsRunning)
            {
                return "服务已停止";
            }
            
            try
            {
                _dnsService.Stop();
                return "服务停止成功";
            }
            catch (Exception ex)
            {
                return $"服务停止失败: {ex.Message}";
            }
        }
        
        private string ExecuteRestartCommand()
        {
            try
            {
                _dnsService.Stop();
                _dnsService.Start();
                return "服务重启成功";
            }
            catch (Exception ex)
            {
                return $"服务重启失败: {ex.Message}";
            }
        }
        
        private string ExecuteListRecordsCommand()
        {
            StringBuilder sb = new StringBuilder();
            
            // 直接读取并解析配置文件中的记录
            List<DnsRecord> allRecords = new List<DnsRecord>();
            
            // 正向配置文件
            string forwardConfigPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Conf", "dns.conf");
            if (File.Exists(forwardConfigPath))
            {
                var lines = File.ReadAllLines(forwardConfigPath);
                foreach (var line in lines)
                {
                    if (!string.IsNullOrWhiteSpace(line) && !line.TrimStart().StartsWith("#"))
                    {
                        var parts = line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
                        if (parts.Length >= 2)
                        {
                            var record = new DnsRecord
                            {
                                IP = parts[0],
                                Domain = parts[1],
                                RecordType = parts.Length > 2 ? parts[2] : "A",
                                Ttl = parts.Length > 3 && int.TryParse(parts[3], out int ttl) ? ttl : 3600,
                                Description = "正向记录"
                            };
                            allRecords.Add(record);
                        }
                    }
                }
            }
            
            // 反向配置文件
            string reverseConfigPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Conf", "dns_reverse.conf");
            if (File.Exists(reverseConfigPath))
            {
                var lines = File.ReadAllLines(reverseConfigPath);
                foreach (var line in lines)
                {
                    if (!string.IsNullOrWhiteSpace(line) && !line.TrimStart().StartsWith("#"))
                    {
                        var parts = line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
                        if (parts.Length >= 2)
                        {
                            var record = new DnsRecord
                            {
                                IP = parts[0],
                                Domain = parts[1],
                                RecordType = parts.Length > 2 ? parts[2] : "PTR",
                                Ttl = parts.Length > 3 && int.TryParse(parts[3], out int ttl) ? ttl : 3600,
                                Description = "反向记录"
                            };
                            allRecords.Add(record);
                        }
                    }
                }
            }
            
            if (allRecords.Count == 0)
            {
                return "当前没有域名解析记录";
            }

            sb.AppendLine($"OK: 共有 {allRecords.Count} 条域名解析记录");
            foreach (var record in allRecords)
            {
                if (string.Equals(record.RecordType, "PTR", StringComparison.OrdinalIgnoreCase))
                {
                    sb.AppendLine($"OK: PTR记录 ({record.IP}:PTR -> {record.Domain}), TTL: {record.Ttl}, {record.Description}");
                }
                else
                {
                    sb.AppendLine($"OK: {record.Domain} -> {record.IP}, TTL: {record.Ttl}, {record.Description}");
                }
            }
            
            return sb.ToString().TrimEnd();
        }
        
        private string ExecuteAddCommand(string[] args)
        {
            string domain = args[0];
            string ip = args[1];
            int ttl = args.Length >= 3 ? int.Parse(args[2]) : 3600;
            string description = args.Length >= 4 ? string.Join(" ", args, 3, args.Length - 3) : string.Empty;
            
            if (_dnsService.AddDnsRecord(domain, ip, "A", ttl, description))
            {
                return $"OK: 成功添加记录 {domain} -> {ip}";
            }
            else
            {
                return $"ERROR: 添加记录失败";
            }
        }
        
        private string ExecuteAddPtrCommand(string[] args)
        {
            string ip = args[0];
            string hostname = args[1];
            int ttl = args.Length >= 3 ? int.Parse(args[2]) : 3600;
            string description = args.Length >= 4 ? string.Join(" ", args, 3, args.Length - 3) : string.Empty;
            
            if (_dnsService.AddDnsRecord(hostname, ip, "PTR", ttl, description))
            {
                return $"OK: 成功添加PTR记录 {ip} -> {hostname}";
            }
            else
            {
                return $"ERROR: 添加PTR记录失败";
            }
        }
        
        private string ExecuteRemoveCommand(string[] args)
        {
            string domain = args[0];
            
            if (_dnsService.RemoveDnsRecord(domain))
            {
                return $"OK: 成功删除记录 {domain}";
            }
            else
            {
                return $"ERROR: 删除记录失败";
            }
        }
        
        private string ExecuteListCommandsCommand()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("可用命令列表：");
            
            foreach (var command in GetAvailableCommands())
            {
                sb.AppendLine($"  {command.Name} - {command.Description}");
            }
            
            return sb.ToString().TrimEnd();
        }
        
        private string ExecuteHelpCommand(string[] args)
        {
            if (args.Length > 0)
            {
                // 查找特定命令的帮助
                var commandName = args[0].ToUpperInvariant();
                var command = CommandRegistry.Commands.FirstOrDefault(c => 
                    string.Equals(c.Name, commandName, StringComparison.OrdinalIgnoreCase));
                
                if (command != null)
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine($"命令: {command.Name}");
                    sb.AppendLine($"格式: {command.Format}");
                    sb.AppendLine($"描述: {command.Description}");
                    if (command.Aliases?.Any() ?? false)
                    {
                        sb.AppendLine($"别名: {string.Join(", ", command.Aliases)}");
                    }
                    return sb.ToString().TrimEnd();
                }
                else
                {
                    return $"未知命令: {commandName}";
                }
            }
            else
            {
                // 显示通用帮助
                return "使用方法: command [parameters]\n使用 LIST_COMMANDS 查看所有可用命令\n使用 HELP command 查看特定命令的帮助";
            }
        }
    }
}